/**
 * 
 */
package com.example.caipiaotrendchart;

import java.util.Observable;
import java.util.Observer;



import android.R.integer;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PaintFlagsDrawFilter;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;


/**
 * 
 * 双色球走势图
 * @author xubh
 *
 */
public class TrendView extends View  implements Observer{

	public static int[][] TestRowRed = new int[][]{
		{6,14,18,22,28,29},
		{7,3,17,20,24,33},
		{3,19,11,24,27,30},

		{7,14,12,26,28,30},
		{1,2,7,20,22,29},
		{1,5,17,18,21,23},

		{2,4,7,22,23,29},
		{3,4,5,7,21,30},
		{6,14,18,22,28,21},

		{3,4,7,26,28,29}
	};

	public static int[] TestRowBlue = new int[]{3,12,11,24,27,33,5,23,2,31};

	static final int kCopies_X = 33;//x 轴分多少份
	static final int kCopies_Y = 10;//y 轴分多少份

	float mDelt_X ;//x 轴每个坐标间的跨度,单位像素,根据实际view大小计算
	float mDelt_Y ;//y 轴每个坐标间的跨度,单位像素，根据实际view大小计算

	int countYLine = 10;//y轴的数量

	//顶部的空白，用于填数字,单位dip
	static final float kTopPadding_Y = 24.0f;
	float mPadding_top;

	private Matrix mMatrix = new Matrix();
	public PaintFlagsDrawFilter mPaintFlagsDrawFilter;// 毛边过滤
	/**
	 * 画笔：线
	 */
	private Paint mLinePaint = new Paint();
	static final float kFontSize = 13;
	float mFontSize;
	/**
	 * 画笔：圆
	 */
	private Paint mCirclePaint = new Paint();
	/**
	 * view的宽高
	 */
	private int mWidth;
	private int mHeight;

	Context mContext;

	/**
	 * 画笔：球
	 */
	private Paint mBallPaint = new Paint();
	private Drawable mCricleDrawable;
	private Bitmap mCricleBmp;

	boolean isNeedLink = false;//是否需要在ball之间连线
	int lineColor;//连线的颜色
	//
	Handler handler = new Handler(){
		public void handleMessage(android.os.Message msg) {
		};
	};
	//用于自动刷新
	Runnable freshRunnable = new Runnable() {
		@Override
		public void run() {
			// TODO Auto-generated method stub
			invalidate();
			handler.postDelayed(this, 500);
		}
	};
	/**
	 * 一些初始化方法
	 */
	public void init(Context context,AttributeSet attrs){
		this.mContext = context;

		TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.TrendView);
		int resId = a.getResourceId(R.styleable.TrendView_ballImage, R.drawable.ball_red);
		isNeedLink = a.getBoolean(R.styleable.TrendView_isNeedLinkEveryBall, false);
		lineColor = a.getColor(R.styleable.TrendView_lineColor, Color.RED);
		a.recycle();

		this.mPaintFlagsDrawFilter = new PaintFlagsDrawFilter(0,
				Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
		this.mCricleDrawable = getResources().getDrawable(
				R.drawable.ball_red);
		this.mCirclePaint.setTextSize(25);
		this.mCirclePaint.setTextScaleX(1.5f);
		this.mLinePaint.setStrokeWidth(2);
		this.mCricleBmp  = BitmapFactory.decodeResource(getResources(), resId);
		this.handler.postDelayed(freshRunnable, 500);
	}
	public TrendView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		// TODO Auto-generated constructor stub
		init(context,attrs);
	}

	public TrendView(Context context, AttributeSet attrs) {
		super(context, attrs);
		// TODO Auto-generated constructor stub
		init(context,attrs);
	}

	@Override
	public void update(Observable observable, Object data) {
		// TODO Auto-generated method stub
		Log.i("observer", "observable >"+observable);
	}

	@Override
	protected void onDraw(Canvas canvas) {
		super.onDraw(canvas);
		canvas.setDrawFilter(mPaintFlagsDrawFilter);
		canvas.drawColor(Color.WHITE);
		drawTopNum(canvas);
		drawXLine(canvas);
		//		drawYLine(canvas);
		drawRightVerticalLine(canvas);
		drawBallLinkLine(canvas);
		drawBall(canvas);

	}
	/**
	 * 画顶部的数字和开始横线
	 * @param cns
	 */
	void drawTopNum(Canvas cns) {
		if (mPadding_top <=0) {
			return;
		}
		mLinePaint.setStrokeWidth(1);
		mLinePaint.setColor(Color.GRAY);
		mLinePaint.setTextSize(mFontSize);
		cns.drawLine(0,  mPadding_top, this.mWidth, mPadding_top, mLinePaint);
		mLinePaint.setColor(Color.RED);
		for (int i = 0;i < kCopies_X;i ++) {
			//写字符时，加点偏移
			if (i >= 9) {
				cns.drawText(String.valueOf(i+1), this.mDelt_X* i + (int)(this.mDelt_X * 0.1f) ,0 + mPadding_top * 0.7f , mLinePaint);
			}else {
				cns.drawText(String.valueOf(i+1), this.mDelt_X* i + (int)(this.mDelt_X * 0.4f) ,0 + mPadding_top * 0.7f, mLinePaint);
			}
		}
	}

	/**
	 * 画y轴,--->
	 * @param canvas
	 */
	void drawXLine(Canvas cns) {
		mLinePaint.setStrokeWidth(1);
		mLinePaint.setColor(Color.GRAY);
		for (int i = 0;i < kCopies_Y;i ++) {
			cns.drawLine(0, this.mDelt_Y* (i + 1) + mPadding_top, this.mWidth, this.mDelt_Y* (i + 1) + mPadding_top, mLinePaint);
		}	
	}

	/**
	 * 画最右边的横线
	 * @param canvas
	 */
	void drawRightVerticalLine(Canvas cns) {
		mLinePaint.setStrokeWidth(4);
		mLinePaint.setColor(Color.GRAY);
		cns.drawLine(mWidth ,0 + mPadding_top , mWidth,this.mHeight,  mLinePaint);
	}

	/**
	 * 画X轴,    ^|
	 * @param canvas
	 */
	void drawYLine(Canvas cns) {
		mLinePaint.setStrokeWidth(1);
		mLinePaint.setColor(Color.GREEN);
		for (int i = 0;i < kCopies_X;i ++) {
			cns.drawLine(this.mDelt_X* (i + 1),0 + mPadding_top , this.mDelt_X* (i + 1),this.mHeight,  mLinePaint);
		}	
	}
	void drawBallLinkLine(Canvas cns) {
		cns.setDrawFilter(mPaintFlagsDrawFilter);
		mLinePaint.setStrokeWidth(2);
		mLinePaint.setColor(lineColor);
		if (isNeedLink) {
			float[] lastXy = this.translateRowIndex2XY(0, TestRowBlue[0] - 1);
			for (int i = 1 ;i < TestRowBlue.length;i ++) {
				int value = TestRowBlue[i];
				float[] xy = this.translateRowIndex2XY(i, value - 1);
				cns.drawLine(lastXy[0]+ mDelt_X * 0.5f,lastXy[1]+ mDelt_Y * 0.5f , xy[0]+ mDelt_X * 0.5f,xy[1]+ mDelt_Y * 0.5f ,  mLinePaint);

				lastXy[0] = xy[0];
				lastXy[1] = xy[1];
			}
		} 
	}

	void drawBall(Canvas cns) {
		mLinePaint.setColor(Color.WHITE);
		mLinePaint.setTextSize(mFontSize - 4);//比顶部字体小点
		Rect src = new Rect();
		Rect dst = new Rect();
		if (isNeedLink) {
			for (int i = 0 ;i < TestRowBlue.length;i ++) {
				int value = TestRowBlue[i];
				float[] xy = this.translateRowIndex2XY(i, value - 1);
				src.left = 0;
				src.top = 0;
				src.bottom = (int) mCricleBmp.getHeight();
				src.right = (int)mCricleBmp.getWidth();

				dst.left = (int) (xy[0] + this.mDelt_X * 0.15f);
				dst.top = (int)(xy[1]+ this.mDelt_Y * 0.15f);
				dst.bottom = (int) (dst.top + mDelt_Y * 0.8f);
				dst.right = (int) (dst.left + mDelt_X * 0.8f);

				//在对应的位置画球球
				cns.drawBitmap(mCricleBmp, src, dst, this.mBallPaint);
				if (value >= 9) {
					cns.drawText(String.valueOf(value), dst.left  + (int)(this.mDelt_X * 0.1f) ,dst.top+ this.mDelt_Y * 0.5f , mLinePaint);
				}else {
					cns.drawText(String.valueOf(value ), dst.left  + (int)(this.mDelt_X * 0.2f) ,dst.top+ this.mDelt_Y * 0.5f , mLinePaint);
				}
			}
		} else {
			//just for test
			//row1
			for (int i = 0;i < TestRowRed.length; i ++) {
				int[] testRow = TestRowRed[i];
				for (int j = 0;j < testRow.length; j ++) {
					int xIndex = testRow[j] ;
					float[] xy = this.translateRowIndex2XY(i, xIndex - 1);

					src.left = 0;
					src.top = 0;
					src.bottom = (int) mCricleBmp.getHeight();
					src.right = (int)mCricleBmp.getWidth();

					//缩小球
					dst.left = (int) (xy[0] + this.mDelt_X * 0.15f);
					dst.top = (int)(xy[1]+ this.mDelt_Y * 0.15f);
					dst.bottom = (int) (dst.top + mDelt_Y * 0.8f);
					dst.right = (int) (dst.left + mDelt_X * 0.8f);

					//在对应的位置画球球
					cns.drawBitmap(mCricleBmp, src, dst, this.mBallPaint);
					if (xIndex >= 9) {
						cns.drawText(String.valueOf(xIndex), dst.left  + (int)(this.mDelt_X * 0.1f) ,dst.top+ this.mDelt_Y * 0.5f , mLinePaint);
					}else {
						cns.drawText(String.valueOf(xIndex ), dst.left  + (int)(this.mDelt_X * 0.2f) ,dst.top+ this.mDelt_Y * 0.5f , mLinePaint);
					}
				}
			}
		}

	}
	/**
	 * 根据位置行和列，转成对应的x,y坐标,不做校正，即都返回左上角坐标 
	 * @param rowIndex  所在行，从0开始
	 * @param xIndex    所在列，从0开始
	 * @return [x0,y0]
	 */
	float[] translateRowIndex2XY (int rowIndex,int xIndex) {
		float[] xy = new float[2];
		xy[0] = this.mDelt_X* xIndex ;
		xy[1] = this.mPadding_top + this.mDelt_Y * rowIndex;
		return xy;
	}
	/**
	 * 根据view的宽高，初始化部分尺寸
	 * @param w
	 * @param h
	 */
	void setViewSize(int w,int h) {
		this.mWidth = w;
		this.mHeight = h;
		this.mDelt_X = 1.0f*this.mWidth  /kCopies_X;
		this.mPadding_top = (float) DimensionPixelUtil.dip2px(mContext, kTopPadding_Y);
		//减去顶部的预留空白后，再均分
		this.mDelt_Y = 1.0f*(this.mHeight  - mPadding_top)/kCopies_Y;

		this.mFontSize =   DimensionPixelUtil.sp2px(mContext, kFontSize);
		invalidate();
	}

	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		System.out.println("onMeasure---widthMeasureSpec::"+widthMeasureSpec +"  heightMeasureSpec::"+heightMeasureSpec);
		int measuredHeight = measureHeight(heightMeasureSpec);

		int measuredWidth = measureWidth(widthMeasureSpec);
		System.out.println("onMeasure---measuredWidth::"+measuredWidth +"  measuredHeight::"+measuredHeight);

		setMeasuredDimension(measuredWidth,measuredHeight);
		this.setViewSize(getMeasuredWidth(),getMeasuredHeight());

	}

	//如果是AT_MOST，specSize 代表的是最大可获得的空间； 
	//如果是EXACTLY，specSize 代表的是精确的尺寸； 
	//如果是UNSPECIFIED，对于控件尺寸来说，没有任何参考意义。

	private int measureHeight(int measureSpec) {
		int specMode = MeasureSpec.getMode(measureSpec);
		int specSize = MeasureSpec.getSize(measureSpec);
		System.out.println("measureHeight----specMode::"+specMode +"  specSize::"+specSize);
		// Default size if no limits are specified.
		int result = 100;
		if (specMode == MeasureSpec.AT_MOST) {

			// Calculate the ideal size of your
			// control within this maximum size.
			// If your control fills the available
			// space return the outer bound.

			result = specSize;
		} else if (specMode == MeasureSpec.EXACTLY) {

			// If your control can fit within these bounds return that value.
			result = specSize;
		}
		return result;
	}

	private int measureWidth(int measureSpec) {
		int specMode = MeasureSpec.getMode(measureSpec);
		int specSize = MeasureSpec.getSize(measureSpec);
		System.out.println("measureWidth----specMode::"+specMode +"  specSize::"+specSize);
		// Default size if no limits are specified.
		int result = 500;
		if (specMode == MeasureSpec.AT_MOST) {
			// Calculate the ideal size of your control
			// within this maximum size.
			// If your control fills the available space
			// return the outer bound.
			result = specSize;
		}

		else if (specMode == MeasureSpec.EXACTLY) {
			// If your control can fit within these bounds return that value.

			result = specSize;
		}

		return result;
	}
}
